package main

import (
	"archive/tar"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"runtime"
	"sort" // 新增: 用于排序版本号
	"strings"

	"github.com/klauspost/compress/zstd"
	"github.com/spf13/cobra"
	"golang.org/x/mod/semver" // 新增: 用于更可靠的版本号排序
)

// --- 全局变量 和 常量 ---
var (
	vvRoot                       string
	shimsDir                     string
	pythonVersionForVenv         string
	pythonBuildStandaloneBaseURL = "https://github.com/indygreg/python-build-standalone/releases/download"
	githubAPIReleasesURL         = "https://api.github.com/repos/indygreg/python-build-standalone/releases"
)

// OS 和 Arch 映射 (提取出来方便复用)
var archMapping = map[string]string{"amd64": "x86_64", "arm64": "aarch64"}
var osMapping = map[string]string{
	"linux":   "unknown-linux-gnu",
	"darwin":  "apple-darwin",
	"windows": "pc-windows-msvc-shared", // 默认使用 shared，可能需要调整
}

// --- GitHub API Structs ---
// GithubAsset, GithubRelease (保持不变)
type GithubAsset struct {
	Name               string `json:"name"`
	BrowserDownloadURL string `json:"browser_download_url"`
}
type GithubRelease struct {
	TagName string        `json:"tag_name"`
	Name    string        `json:"name"`
	Assets  []GithubAsset `json:"assets"`
}

// --- Helper Functions ---

// getPythonInstallDir 返回存放所有 Python 安装的目录
func getPythonInstallDir() string {
	return filepath.Join(vvRoot, "pythons")
}

// getSpecificPythonDir 返回特定 Python 版本的安装目录
func getSpecificPythonDir(version string) string {
	return filepath.Join(getPythonInstallDir(), version)
}

// getShimsDir 返回 shims 目录
func getShimsDir() string {
	return filepath.Join(vvRoot, "shims")
}

// getCurrentPlatformIdentifiers 获取当前平台的 OS 和 Arch 标识符
func getCurrentPlatformIdentifiers() (osIdentifier string, archIdentifier string, err error) {
	goos := runtime.GOOS
	goarch := runtime.GOARCH

	archIdentifier, okArch := archMapping[goarch]
	osIdentifier, okOS := osMapping[goos]

	if !okArch || !okOS {
		err = fmt.Errorf("不支持的操作系统/架构组合: %s/%s", goos, goarch)
		return
	}
	return
}

// findPythonExecutable 查找给定版本 Python 的主可执行文件路径
func findPythonExecutable(version string) (string, error) {
	installDir := getSpecificPythonDir(version)
	var potentialPaths []string
	if runtime.GOOS == "windows" {
		potentialPaths = []string{
			filepath.Join(installDir, "python", "python.exe"),
		}
	} else {
		potentialPaths = []string{
			filepath.Join(installDir, "python", "bin", "python3"), // 优先 python3
			filepath.Join(installDir, "python", "bin", "python"),
		}
	}

	for _, pPath := range potentialPaths {
		if _, err := os.Stat(pPath); err == nil {
			return pPath, nil
		}
	}
	return "", fmt.Errorf("在 %s 中未找到 Python 可执行文件", installDir)
}

// findShimTarget 查找特定 shim 对应的目标可执行文件路径
func findShimTarget(shimName, versionDir string) (string, error) {
	var targetPath string
	if runtime.GOOS == "windows" {
		scriptDir := filepath.Join(versionDir, "python", "Scripts")
		targetPath = filepath.Join(scriptDir, shimName+".exe")
		if _, err := os.Stat(targetPath); err != nil {
			if shimName == "python" || shimName == "python3" {
				targetPath = filepath.Join(versionDir, "python", "python.exe")
				if _, err := os.Stat(targetPath); err != nil {
					return "", fmt.Errorf("未找到目标 %s.exe 或 python.exe", shimName)
				}
			} else {
				return "", fmt.Errorf("未找到目标 %s.exe", shimName)
			}
		}
	} else {
		binDir := filepath.Join(versionDir, "python", "bin")
		targetPath = filepath.Join(binDir, shimName)
		if _, err := os.Stat(targetPath); err != nil {
			if shimName == "python3" {
				targetPath = filepath.Join(binDir, "python")
				if _, err := os.Stat(targetPath); err != nil {
					return "", fmt.Errorf("未找到目标 %s 或 python", shimName)
				}
			} else if shimName == "pip3" {
				targetPath = filepath.Join(binDir, "pip")
				if _, err := os.Stat(targetPath); err != nil {
					return "", fmt.Errorf("未找到目标 %s 或 pip", shimName)
				}
			} else {
				return "", fmt.Errorf("未找到目标 %s", shimName)
			}
		}
	}
	return targetPath, nil
}

// createShim 创建指向目标可执行文件的 shim
func createShim(shimName, targetExecutable string) error {
	shimPath := filepath.Join(getShimsDir(), shimName)
	if runtime.GOOS == "windows" {
		shimPath += ".bat"
	}

	if _, err := os.Lstat(shimPath); err == nil {
		if err := os.Remove(shimPath); err != nil {
			return fmt.Errorf("无法移除已存在的 shim %s: %w", shimPath, err)
		}
	} else if !os.IsNotExist(err) {
		return fmt.Errorf("检查 shim %s 时出错: %w", shimPath, err)
	}

	if runtime.GOOS == "windows" {
		absTarget, err := filepath.Abs(targetExecutable)
		if err != nil {
			return fmt.Errorf("无法获取目标绝对路径 %s: %w", targetExecutable, err)
		}
		content := fmt.Sprintf("@\"%s\" %%*", absTarget)
		err = os.WriteFile(shimPath, []byte(content), 0755)
		if err != nil {
			return fmt.Errorf("无法创建 shim 脚本 %s: %w", shimPath, err)
		}
		fmt.Printf("  Created shim: %s -> %s\n", shimPath, targetExecutable)
	} else {
		err := os.Symlink(targetExecutable, shimPath)
		if err != nil {
			return fmt.Errorf("无法创建符号链接 %s -> %s: %w", shimPath, targetExecutable, err)
		}
		fmt.Printf("  Created symlink: %s -> %s\n", shimPath, targetExecutable)
	}
	return nil
}

// downloadFile, extractTarArchive, extractTarZst (保持不变)
// ... (函数体省略) ...
func downloadFile(url string, destPath string) error {
	fmt.Printf("Downloading %s to %s\n", url, destPath)
	out, err := os.Create(destPath)
	if err != nil {
		return fmt.Errorf("无法创建目标文件 %s: %w", destPath, err)
	}
	defer out.Close()

	client := &http.Client{}
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return fmt.Errorf("创建请求失败 %s: %w", url, err)
	}
	req.Header.Set("User-Agent", "vv-go-tool/0.1")
	req.Header.Set("Accept", "application/octet-stream") // 请求二进制流

	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf("下载失败 %s: %w", url, err)
	}
	defer resp.Body.Close()

	if resp.StatusCode == http.StatusNotFound {
		return fmt.Errorf("下载失败 %s: 未找到文件 (404)。请检查版本号、操作系统、架构是否匹配可用版本。", url)
	}
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("下载失败 %s: 服务器返回状态 %s", url, resp.Status)
	}

	// TODO: 添加下载进度条
	_, err = io.Copy(out, resp.Body)
	if err != nil {
		os.Remove(destPath)
		return fmt.Errorf("写入文件失败 %s: %w", destPath, err)
	}
	fmt.Println("Download complete.")
	return nil
}
func extractTarArchive(tarStream io.Reader, destDir string) error {
	tarReader := tar.NewReader(tarStream)
	fmt.Printf("Extracting archive to %s...\n", destDir)
	for {
		header, err := tarReader.Next()
		if err == io.EOF {
			break // End of archive
		}
		if err != nil {
			return fmt.Errorf("读取 tar 归档失败: %w", err)
		}

		targetPath := filepath.Join(destDir, header.Name)
		// 安全性：防止路径遍历攻击 (虽然来自可信源，但最好有)
		cleanDestDir := filepath.Clean(destDir)
		if !strings.HasPrefix(targetPath, cleanDestDir+string(os.PathSeparator)) && targetPath != cleanDestDir {
			return fmt.Errorf("不安全的 tar entry: %s", header.Name)
		}

		// 根据 header 类型处理
		switch header.Typeflag {
		case tar.TypeDir: // 目录
			if err := os.MkdirAll(targetPath, os.FileMode(header.Mode)); err != nil {
				return fmt.Errorf("创建目录失败 %s: %w", targetPath, err)
			}
		case tar.TypeReg: // 普通文件
			// 确保父目录存在
			if err := os.MkdirAll(filepath.Dir(targetPath), os.ModePerm); err != nil {
				return fmt.Errorf("创建父目录失败 %s: %w", filepath.Dir(targetPath), err)
			}

			// 创建文件
			outFile, err := os.OpenFile(targetPath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.FileMode(header.Mode))
			if err != nil {
				return fmt.Errorf("创建文件失败 %s: %w", targetPath, err)
			}
			// 将文件内容从 tar 复制到目标文件
			if _, err := io.Copy(outFile, tarReader); err != nil {
				outFile.Close() // 确保关闭文件句柄
				return fmt.Errorf("写入文件失败 %s: %w", targetPath, err)
			}
			outFile.Close() // 关闭文件
		case tar.TypeSymlink: // 符号链接
			linkTarget := header.Linkname
			// 确保目标目录存在 (如果链接本身在根目录)
			linkDir := filepath.Dir(targetPath)
			if linkDir != "." && linkDir != destDir {
				if err := os.MkdirAll(linkDir, os.ModePerm); err != nil {
					return fmt.Errorf("创建符号链接的父目录失败 %s: %w", linkDir, err)
				}
			}
			// 尝试创建符号链接
			if err := os.Symlink(linkTarget, targetPath); err != nil {
				fmt.Printf("警告: 创建符号链接失败 %s -> %s: %v (可能是权限问题)\n", targetPath, linkTarget, err)
			}
		case tar.TypeLink: // 硬链接 (通常不需要特殊处理)
			fmt.Printf("Skipping hard link (treating as regular file if content present): %s -> %s\n", targetPath, header.Linkname)
		default:
			fmt.Printf("Skipping unsupported tar entry type %c for %s\n", header.Typeflag, targetPath)
		}
	}
	fmt.Println("Extraction complete.")
	return nil
}
func extractTarZst(zstStream io.Reader, destDir string) error {
	zstdReader, err := zstd.NewReader(zstStream)
	if err != nil {
		return fmt.Errorf("创建 zstd reader 失败: %w", err)
	}
	defer zstdReader.Close()
	return extractTarArchive(zstdReader, destDir)
}

// findPythonDownloadURL 通过 GitHub API 查找特定版本的下载链接
func findPythonDownloadURL(version, targetOS, targetArch string) (string, string, error) {
	fmt.Printf("正在查找 Python %s (%s/%s) 的下载链接...\n", version, targetOS, targetArch)
	client := &http.Client{}
	req, err := http.NewRequest("GET", githubAPIReleasesURL, nil)
	if err != nil {
		return "", "", fmt.Errorf("创建 GitHub API 请求失败: %w", err)
	}
	req.Header.Set("Accept", "application/vnd.github.v3+json")
	req.Header.Set("User-Agent", "vv-go-tool/0.1")

	resp, err := client.Do(req)
	if err != nil {
		return "", "", fmt.Errorf("请求 GitHub API 失败: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		bodyBytes, _ := io.ReadAll(resp.Body)
		return "", "", fmt.Errorf("GitHub API 请求失败: 状态 %s, 响应: %s", resp.Status, string(bodyBytes))
	}

	var releases []GithubRelease
	if err := json.NewDecoder(resp.Body).Decode(&releases); err != nil {
		return "", "", fmt.Errorf("解析 GitHub API 响应失败: %w", err)
	}

	// 正则表达式匹配特定版本的文件名
	pattern := fmt.Sprintf(`^cpython-%s\+(\d{8})-%s-%s-install_only\.tar\.zst$`,
		regexp.QuoteMeta(version),
		regexp.QuoteMeta(targetArch),
		regexp.QuoteMeta(targetOS),
	)
	re, err := regexp.Compile(pattern)
	if err != nil {
		return "", "", fmt.Errorf("无效的正则表达式模式 %s: %w", pattern, err)
	}
	// fmt.Printf("使用正则表达式查找资源文件: %s\n", pattern) // 调试信息

	for _, release := range releases {
		for _, asset := range release.Assets {
			if re.MatchString(asset.Name) {
				// fmt.Printf("找到匹配资源: %s\n", asset.Name) // 调试信息
				return asset.BrowserDownloadURL, asset.Name, nil
			}
		}
	}

	return "", "", fmt.Errorf("未找到适用于 Python %s (%s/%s) 的兼容预编译版本", version, targetOS, targetArch)
}

// findAvailablePythonVersions 查找当前平台可用的所有 Python 版本
func findAvailablePythonVersions() ([]string, error) {
	fmt.Println("正在从 GitHub API 获取可用的 Python 版本...")
	targetOS, targetArch, err := getCurrentPlatformIdentifiers()
	if err != nil {
		return nil, fmt.Errorf("无法确定当前平台标识符: %w", err)
	}

	client := &http.Client{}
	req, err := http.NewRequest("GET", githubAPIReleasesURL, nil)
	if err != nil {
		return nil, fmt.Errorf("创建 GitHub API 请求失败: %w", err)
	}
	req.Header.Set("Accept", "application/vnd.github.v3+json")
	req.Header.Set("User-Agent", "vv-go-tool/0.1")

	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("请求 GitHub API 失败: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		bodyBytes, _ := io.ReadAll(resp.Body)
		return nil, fmt.Errorf("GitHub API 请求失败: 状态 %s, 响应: %s", resp.Status, string(bodyBytes))
	}

	var releases []GithubRelease
	if err := json.NewDecoder(resp.Body).Decode(&releases); err != nil {
		return nil, fmt.Errorf("解析 GitHub API 响应失败: %w", err)
	}

	// 正则表达式提取版本号 (匹配 cpython-<version>+<date>-<arch>-<os>-install_only.tar.zst)
	// 使用捕获组提取 <version> 部分
	pattern := fmt.Sprintf(`^cpython-([0-9]+\.[0-9]+\.[0-9]+(?:-[a-zA-Z0-9.]+)?)\+\d{8}-%s-%s-install_only\.tar\.zst$`,
		regexp.QuoteMeta(targetArch),
		regexp.QuoteMeta(targetOS),
	)
	re, err := regexp.Compile(pattern)
	if err != nil {
		return nil, fmt.Errorf("无效的正则表达式模式 %s: %w", pattern, err)
	}
	// fmt.Printf("使用正则表达式提取可用版本: %s\n", pattern) // 调试信息

	availableVersionsMap := make(map[string]struct{}) // 使用 map 去重

	for _, release := range releases {
		for _, asset := range release.Assets {
			matches := re.FindStringSubmatch(asset.Name)
			if len(matches) > 1 {
				version := matches[1] // 第一个捕获组是版本号
				// 添加 'v' 前缀以便使用 semver 排序
				if !strings.HasPrefix(version, "v") {
					version = "v" + version
				}
				availableVersionsMap[version] = struct{}{}
			}
		}
	}

	// 将 map 的键（版本号）转换为 slice
	versions := make([]string, 0, len(availableVersionsMap))
	for v := range availableVersionsMap {
		versions = append(versions, v)
	}

	// 使用 semver 进行排序
	sort.SliceStable(versions, func(i, j int) bool {
		// semver.Compare 对于预发布版本可能需要特殊处理，但通常能正确排序
		// 如果 'v' 前缀导致问题，可以在排序前去除，排序后再加回
		return semver.Compare(versions[i], versions[j]) < 0
	})

	// 移除 'v' 前缀用于显示
	for i, v := range versions {
		versions[i] = strings.TrimPrefix(v, "v")
	}

	fmt.Printf("找到 %d 个适用于 %s/%s 的可用版本。\n", len(versions), targetOS, targetArch)
	return versions, nil
}

// --- rootCmd: 根命令 'vv' ---
var rootCmd = &cobra.Command{
	Use:   "vv",
	Short: "vv 是一个 Go 驱动的 Python 工作流工具",
	Long: `vv 旨在提供快速、统一的 Python 版本管理、
依赖管理和虚拟环境管理体验。
灵感来源于 uv。`,
	PersistentPreRun: func(cmd *cobra.Command, args []string) {
		homeDir, err := os.UserHomeDir()
		if err != nil {
			log.Fatalf("无法获取用户主目录: %v", err)
		}
		vvRoot = filepath.Join(homeDir, ".vv")
		if err := os.MkdirAll(getPythonInstallDir(), os.ModePerm); err != nil {
			log.Fatalf("无法创建 vv Python 安装目录 %s: %v", getPythonInstallDir(), err)
		}
		shimsDir = getShimsDir()
		if err := os.MkdirAll(shimsDir, os.ModePerm); err != nil {
			log.Fatalf("无法创建 vv shims 目录 %s: %v", shimsDir, err)
		}
	},
}

// --- venvCmd: 'vv venv' 子命令 ---
var venvCmd = &cobra.Command{
	// ... (保持不变) ...
	Use:   "venv [path]",
	Short: "创建 Python 虚拟环境",
	Long:  `在指定路径创建 Python 虚拟环境。默认为当前目录下的 '.venv'。`,
	Args:  cobra.MaximumNArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		venvPath := ".venv"
		if len(args) > 0 {
			venvPath = args[0]
		}
		absVenvPath, err := filepath.Abs(venvPath)
		if err != nil {
			log.Fatalf("无法获取绝对路径 %s: %v", venvPath, err)
		}

		// --- 确定 Python 可执行文件 ---
		pythonExecutable := ""
		if pythonVersionForVenv != "" {
			// 尝试从 vv 管理的版本中查找
			var findErr error
			pythonExecutable, findErr = findPythonExecutable(pythonVersionForVenv)
			if findErr != nil {
				log.Printf("警告: 找不到 vv 管理的 Python 版本 %s (%v)，将尝试系统 PATH。", pythonVersionForVenv, findErr)
			} else {
				fmt.Printf("使用 vv 管理的 Python 版本: %s\n", pythonExecutable)
			}
		}

		// 如果没有指定版本或找不到 vv 管理的版本，则回退到系统 PATH
		if pythonExecutable == "" {
			systemPython := "python3"
			if _, err := exec.LookPath(systemPython); err != nil {
				systemPython = "python"
				if _, err := exec.LookPath(systemPython); err != nil {
					log.Fatalf("错误: 在 PATH 中找不到 'python' 或 'python3' 可执行文件。请确保已安装 Python 或使用 'vv python install' 安装。")
				}
			}
			pythonExecutable = systemPython
			fmt.Printf("使用系统 PATH 中的 Python: %s\n", pythonExecutable)
		}
		// --- Python 可执行文件确定结束 ---

		fmt.Printf("将在 %s 创建虚拟环境 (使用 %s)...\n", absVenvPath, pythonExecutable)

		// 检查目标路径是否已存在且非空，避免覆盖
		if _, err := os.Stat(absVenvPath); err == nil {
			dirEntries, err := os.ReadDir(absVenvPath)
			if err != nil {
				log.Fatalf("无法读取目标目录 %s: %v", absVenvPath, err)
			}
			if len(dirEntries) > 0 {
				isEmpty := true
				for _, entry := range dirEntries {
					if !strings.HasPrefix(entry.Name(), ".") {
						isEmpty = false
						break
					}
				}
				if !isEmpty {
					log.Fatalf("错误: 目标路径 %s 已存在且非空。请删除或选择其他路径。", absVenvPath)
				} else {
					fmt.Println("目标路径存在但为空，将继续创建。")
				}
			}
		} else if !os.IsNotExist(err) {
			log.Fatalf("检查目标路径 %s 时出错: %v", absVenvPath, err)
		}

		venvCmd := exec.Command(pythonExecutable, "-m", "venv", absVenvPath)
		venvCmd.Stdout = os.Stdout
		venvCmd.Stderr = os.Stderr

		if err := venvCmd.Run(); err != nil {
			log.Fatalf("创建虚拟环境失败: %v", err)
		}

		fmt.Printf("虚拟环境 %s 创建成功。\n", absVenvPath)
		fmt.Println("要激活它，请运行:")
		var activateScript string
		if runtime.GOOS == "windows" {
			activateScript = filepath.Join(absVenvPath, "Scripts", "activate")
			fmt.Printf("  %s\n", activateScript)
		} else {
			activateScript = filepath.Join(absVenvPath, "bin", "activate")
			fmt.Printf("  source %s\n", activateScript)
		}
	},
}

// --- pythonCmd: 'vv python' 父命令 ---
var pythonCmd = &cobra.Command{
	Use:   "python",
	Short: "管理 Python 安装",
	Long:  `管理由 vv 下载和安装的 Python 版本。`,
}

// --- pythonListCmd: 'vv python list' 子命令 ---
var pythonListCmd = &cobra.Command{
	Use:   "list",
	Short: "列出已安装或可用的 Python 版本",
	Run: func(cmd *cobra.Command, args []string) {
		available, _ := cmd.Flags().GetBool("available")
		installDir := getPythonInstallDir()

		if available {
			// --- 显示可用版本 ---
			versions, err := findAvailablePythonVersions()
			if err != nil {
				log.Fatalf("获取可用 Python 版本失败: %v", err)
			}
			if len(versions) == 0 {
				fmt.Println("未能找到适用于当前平台的可用 Python 版本。")
			} else {
				fmt.Println("可供安装的 Python 版本 (适用于当前平台):")
				for _, v := range versions {
					fmt.Printf(" - %s\n", v)
				}
			}
		} else {
			// --- 显示已安装版本 ---
			fmt.Printf("已安装的 Python 版本 (位于 %s):\n", installDir)
			entries, err := os.ReadDir(installDir)
			if err != nil {
				if os.IsNotExist(err) {
					fmt.Println("  (尚未安装任何版本)")
					return
				}
				log.Fatalf("无法读取 Python 安装目录 %s: %v", installDir, err)
			}

			found := false
			var installedVersions []string
			for _, entry := range entries {
				if entry.IsDir() {
					version := entry.Name()
					if _, err := findPythonExecutable(version); err == nil {
						// 添加 'v' 前缀用于排序
						if !strings.HasPrefix(version, "v") {
							version = "v" + version
						}
						installedVersions = append(installedVersions, version)
						found = true
					}
				}
			}

			if !found {
				fmt.Println("  (尚未安装任何有效版本)")
			} else {
				// 排序已安装版本
				sort.SliceStable(installedVersions, func(i, j int) bool {
					return semver.Compare(installedVersions[i], installedVersions[j]) < 0
				})
				// 移除 'v' 前缀并打印
				for _, v := range installedVersions {
					fmt.Printf(" - %s\n", strings.TrimPrefix(v, "v"))
				}
			}
		}
	},
}

// --- pythonInstallCmd: 'vv python install' 子命令 ---
var pythonInstallCmd = &cobra.Command{
	// ... (保持不变) ...
	Use:   "install <version>",
	Short: "下载并安装指定的 Python 版本",
	Long: `从 python-build-standalone 的 GitHub Releases 自动查找、下载并安装
指定版本的预编译 Python。`,
	Args: cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		version := args[0]
		targetDir := getSpecificPythonDir(version)

		// 1. 检查版本是否已安装
		installedPythonExe, err := findPythonExecutable(version)
		if err == nil {
			fmt.Printf("Python 版本 %s 似乎已安装在 %s\n", version, targetDir)
			cmd := exec.Command(installedPythonExe, "--version")
			output, _ := cmd.CombinedOutput()
			fmt.Printf("  已安装版本: %s", string(output))
			return
		}
		if _, err := os.Stat(targetDir); err == nil && !os.IsNotExist(err) {
			log.Printf("警告: 目标目录 %s 存在但似乎不包含有效的 Python 安装。将尝试覆盖。", targetDir)
		}

		// 2. 确定目标 OS 和架构标识符
		targetOS, targetArch, err := getCurrentPlatformIdentifiers()
		if err != nil {
			log.Fatalf("无法确定当前平台标识符: %v", err)
		}

		// 3. 使用 GitHub API 查找下载 URL 和文件名
		downloadURL, archiveName, err := findPythonDownloadURL(version, targetOS, targetArch)
		if err != nil {
			log.Fatalf("查找 Python %s (%s/%s) 下载链接失败: %v", version, targetOS, targetArch, err)
		}
		if downloadURL == "" || archiveName == "" {
			log.Fatalf("未能从 GitHub API 获取有效的下载链接或文件名。")
		}

		// 4. 下载归档文件
		tempDir, err := os.MkdirTemp("", "vv-download-")
		if err != nil {
			log.Fatalf("无法创建临时目录: %v", err)
		}
		defer os.RemoveAll(tempDir)
		archivePath := filepath.Join(tempDir, archiveName)
		if err := downloadFile(downloadURL, archivePath); err != nil {
			log.Fatalf("下载 Python %s 失败: %v", version, err)
		}

		// 5. 解压归档文件到目标目录
		fmt.Println("开始解压...")
		archiveFile, err := os.Open(archivePath)
		if err != nil {
			log.Fatalf("无法打开下载的归档文件 %s: %v", archivePath, err)
		}
		defer archiveFile.Close()
		if _, err := os.Stat(targetDir); err == nil {
			fmt.Printf("正在清理已存在的目标目录: %s\n", targetDir)
			if err := os.RemoveAll(targetDir); err != nil {
				log.Fatalf("清理目标目录 %s 失败: %v", targetDir, err)
			}
		}
		if err := os.MkdirAll(targetDir, os.ModePerm); err != nil {
			log.Fatalf("无法创建目标安装目录 %s: %v", targetDir, err)
		}
		err = extractTarZst(archiveFile, targetDir)
		if err != nil {
			fmt.Printf("解压失败，正在清理目标目录 %s...\n", targetDir)
			os.RemoveAll(targetDir)
			log.Fatalf("解压 Python %s 失败: %v", version, err)
		}
		fmt.Printf("Python 版本 %s 成功安装到: %s\n", version, targetDir)

		// 验证安装
		verifyExePath, err := findPythonExecutable(version)
		if err != nil {
			fmt.Printf("警告: 安装后无法找到 Python 可执行文件进行验证: %v\n", err)
		} else {
			cmd := exec.Command(verifyExePath, "--version")
			output, err := cmd.CombinedOutput()
			if err != nil {
				fmt.Printf("警告: 验证安装时执行 %s --version 失败: %v\n Output: %s\n", verifyExePath, err, string(output))
			} else {
				fmt.Printf("验证成功: %s\n", strings.TrimSpace(string(output)))
			}
		}
	},
}

// --- pythonUseCmd: 'vv python use' 子命令 ---
var pythonUseCmd = &cobra.Command{
	// ... (保持不变) ...
	Use:   "use <version>",
	Short: "切换当前使用的 Python 版本",
	Long: `切换全局或项目的 Python 版本。
全局切换 (--global) 会更新 ~/.vv/shims 目录中的链接/脚本。
你需要将 ~/.vv/shims 添加到你的 PATH 环境变量中才能生效。
项目切换 (默认，暂未实现) 会在当前目录创建 .python-version 文件。`,
	Args: cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		version := args[0]
		isGlobal, _ := cmd.Flags().GetBool("global")
		// isProject, _ := cmd.Flags().GetBool("project") // 暂未使用

		// 检查版本是否已安装
		versionDir := getSpecificPythonDir(version)
		if _, err := findPythonExecutable(version); err != nil {
			log.Fatalf("错误: Python 版本 %s 未安装或安装不完整。请先使用 'vv python install %s' 安装。", version, version)
		}

		if isGlobal {
			// --- 全局切换逻辑 ---
			fmt.Printf("正在设置全局 Python 版本为 %s...\n", version)
			shimsToCreate := []string{"python", "python3", "pip", "pip3"}
			if runtime.GOOS == "windows" {
				shimsToCreate = []string{"python", "pip"}
			}

			fmt.Printf("将在 %s 中创建/更新 shims:\n", shimsDir)
			successCount := 0
			failCount := 0

			for _, shimName := range shimsToCreate {
				targetExe, err := findShimTarget(shimName, versionDir)
				if err != nil {
					fmt.Printf("  Skipping shim '%s': %v\n", shimName, err)
					continue
				}
				if err := createShim(shimName, targetExe); err != nil {
					log.Printf("  错误: 创建 shim '%s' 失败: %v", shimName, err)
					failCount++
				} else {
					successCount++
				}
			}

			if failCount > 0 {
				log.Printf("警告: %d 个 shim 创建失败。\n", failCount)
			}
			if successCount > 0 {
				fmt.Printf("成功创建/更新 %d 个 shim。\n", successCount)
				fmt.Println("\n重要提示:")
				fmt.Println("请确保将以下目录添加到您的 PATH 环境变量中，以便使用设置的全局版本:")
				fmt.Printf("  %s\n", shimsDir)
				fmt.Println("具体方法取决于您的操作系统和 shell:")
				fmt.Println("  - Linux/macOS (bash/zsh): 添加 'export PATH=\"$HOME/.vv/shims:$PATH\"' 到 ~/.bashrc 或 ~/.zshrc")
				fmt.Println("  - Windows: 通过系统属性 -> 高级系统设置 -> 环境变量，编辑用户的 PATH 变量。")
				fmt.Println("修改 PATH 后需要重启 shell 或终端才能生效。")
			} else {
				fmt.Println("没有创建任何 shim。")
			}

		} else {
			// --- 项目切换逻辑 (暂未实现) ---
			fmt.Println("功能未实现: 设置项目 Python 版本。")
			fmt.Println("如果实现，将在当前目录创建 .python-version 文件:")
			fmt.Printf("  echo \"%s\" > .python-version\n", version)
			fmt.Println("vv 的其他命令（如 install, run）需要实现逻辑来读取此文件并优先使用指定的版本。")
			// TODO: 实现创建 .python-version 文件
		}
	},
}

// --- pythonUninstallCmd: 'vv python uninstall' 子命令 ---
var pythonUninstallCmd = &cobra.Command{
	// ... (保持不变) ...
	Use:   "uninstall <version>",
	Short: "卸载指定的 Python 版本",
	Args:  cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		version := args[0]
		targetDir := getSpecificPythonDir(version)

		fmt.Printf("尝试卸载 Python 版本 %s (位于 %s)...\n", version, targetDir)

		if _, err := os.Stat(targetDir); os.IsNotExist(err) {
			fmt.Printf("Python 版本 %s 未找到，无需卸载。\n", version)
			return
		}

		// TODO: 检查此版本是否当前全局版本，如果是，给出警告或建议先切换
		// TODO: (可选) 清理 shims 目录中指向已卸载版本的无效链接/脚本

		err := os.RemoveAll(targetDir)
		if err != nil {
			log.Fatalf("卸载 Python 版本 %s 失败: %v", version, err)
		}

		fmt.Printf("Python 版本 %s 卸载成功。\n", version)

	},
}

// --- installCmd: 'vv install' 命令 ---
var installCmd = &cobra.Command{
	// ... (保持不变) ...
	Use:   "install [package...]",
	Short: "安装依赖项 (功能未实现)",
	Long: `从 pyproject.toml 或 requirements.txt 安装依赖项，
或者安装指定的包。依赖解析和包安装是复杂功能，尚未实现。`,
	Run: func(cmd *cobra.Command, args []string) {
		requirementsFile, _ := cmd.Flags().GetString("requirement")

		// --- 自动检测虚拟环境 ---
		venvPath := ".venv" // 默认检查路径
		absVenvPath, _ := filepath.Abs(venvPath)
		var pipExecutable string
		// var pythonExecutable string // 同时获取 venv 的 python

		if runtime.GOOS == "windows" {
			pipExecutable = filepath.Join(absVenvPath, "Scripts", "pip.exe")
			// pythonExecutable = filepath.Join(absVenvPath, "Scripts", "python.exe")
		} else {
			pipExecutable = filepath.Join(absVenvPath, "bin", "pip")
			// pythonExecutable = filepath.Join(absVenvPath, "bin", "python")
		}

		hasVenv := false
		if _, err := os.Stat(pipExecutable); err == nil {
			hasVenv = true
			fmt.Printf("检测到活动的虚拟环境: %s\n", absVenvPath)
		} else {
			fmt.Println("警告: 未在默认路径 .venv 检测到活动的虚拟环境。依赖管理命令通常需要激活的虚拟环境。")
		}
		// --- 虚拟环境检测结束 ---

		if requirementsFile != "" {
			fmt.Printf("功能未实现: 从 %s 安装依赖\n", requirementsFile)
			if hasVenv {
				fmt.Printf("  (如果实现，将使用 %s install -r %s)\n", pipExecutable, requirementsFile)
			}
			// TODO: 实现调用 pip 安装 requirements.txt
		} else if len(args) > 0 {
			fmt.Printf("功能未实现: 安装包: %v\n", args)
			if hasVenv {
				fmt.Printf("  (如果实现，将使用 %s install %s)\n", pipExecutable, strings.Join(args, " "))
			}
			// TODO: 实现调用 pip 安装指定包，或者实现自己的包查找、下载、安装逻辑 (非常复杂)
		} else {
			pyprojectPath := "pyproject.toml"
			if _, err := os.Stat(pyprojectPath); err == nil {
				fmt.Println("功能未实现: 从 pyproject.toml 安装依赖")
				if hasVenv {
					fmt.Printf("  (如果实现，将解析 %s 并使用 %s 安装)\n", pyprojectPath, pipExecutable)
				}
				// TODO: 解析 pyproject.toml，进行依赖解析，下载并安装 (核心挑战)
			} else {
				fmt.Println("当前目录下未找到 pyproject.toml，也未指定包或 requirements 文件。")
			}
		}
	},
}

// --- 其他依赖管理命令 (add, remove, lock, sync, freeze) 保持不变 ---
// ... (代码省略) ...
var addCmd = &cobra.Command{
	Use:   "add <package>",
	Short: "添加依赖项到 pyproject.toml 并安装 (功能未实现)",
	Args:  cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		pkg := args[0]
		isDev, _ := cmd.Flags().GetBool("dev")
		fmt.Printf("功能未实现: 添加包 %s (Dev: %t)\n", pkg, isDev)
		// TODO: 解析 pyproject.toml, 添加依赖 (需要 TOML 编辑库), 调用 install 安装包
	},
}
var removeCmd = &cobra.Command{
	Use:   "remove <package>",
	Short: "从 pyproject.toml 移除依赖项并卸载 (功能未实现)",
	Args:  cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		pkg := args[0]
		isDev, _ := cmd.Flags().GetBool("dev")
		fmt.Printf("功能未实现: 移除包 %s (Dev: %t)\n", pkg, isDev)
		// TODO: 解析 pyproject.toml, 移除依赖 (需要 TOML 编辑库), 调用 pip uninstall 卸载包
	},
}
var lockCmd = &cobra.Command{
	Use:   "lock",
	Short: "根据 pyproject.toml 生成锁文件 (vv.lock) (功能未实现)",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("功能未实现: 生成锁文件 vv.lock")
		// TODO: 实现依赖解析并生成锁文件 (核心挑战)
	},
}
var syncCmd = &cobra.Command{
	Use:   "sync",
	Short: "根据锁文件 (vv.lock) 同步虚拟环境 (功能未实现)",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("功能未实现: 同步环境与 vv.lock")
		// TODO: 读取 vv.lock 并安装/卸载包以匹配锁文件 (可能调用 pip)
	},
}
var freezeCmd = &cobra.Command{
	Use:   "freeze",
	Short: "将当前环境的包输出为 requirements.txt 格式 (功能未实现)",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("功能未实现: freeze 环境")
		// --- 查找 venv pip ---
		venvPath := ".venv"
		absVenvPath, _ := filepath.Abs(venvPath)
		var pipExecutable string
		if runtime.GOOS == "windows" {
			pipExecutable = filepath.Join(absVenvPath, "Scripts", "pip.exe")
		} else {
			pipExecutable = filepath.Join(absVenvPath, "bin", "pip")
		}
		if _, err := os.Stat(pipExecutable); err == nil {
			fmt.Printf("  (如果实现，将执行 %s freeze)\n", pipExecutable)
			// output, err := exec.Command(pipExecutable, "freeze").Output()
			// if err != nil { log.Fatalf(...) }
			// fmt.Println(string(output))
		} else {
			fmt.Println("  错误: 未找到虚拟环境的 pip。")
		}
	},
}

// --- 初始化函数 ---
func init() {
	// 添加 venv 命令
	venvCmd.Flags().StringVarP(&pythonVersionForVenv, "python", "p", "", "用于创建虚拟环境的 Python 版本 (例如 3.11)，需要先用 vv 安装")
	rootCmd.AddCommand(venvCmd)

	// 添加 python 子命令
	// 更新 list 命令的描述
	pythonListCmd.Flags().Bool("available", false, "显示当前平台可供安装的 Python 版本")
	pythonCmd.AddCommand(pythonListCmd)
	pythonCmd.AddCommand(pythonInstallCmd)
	pythonUseCmd.Flags().Bool("global", false, "设置为全局 Python 版本 (更新 shims)")
	pythonUseCmd.Flags().Bool("project", false, "设置为当前项目的 Python 版本 (创建 .python-version, 暂未实现)")
	pythonCmd.AddCommand(pythonUseCmd)
	pythonCmd.AddCommand(pythonUninstallCmd)
	rootCmd.AddCommand(pythonCmd)

	// 添加依赖管理命令
	installCmd.Flags().StringP("requirement", "r", "", "从给定的需求文件安装 (暂未实现)")
	rootCmd.AddCommand(installCmd)
	addCmd.Flags().Bool("dev", false, "添加为开发依赖项 (暂未实现)")
	rootCmd.AddCommand(addCmd)
	removeCmd.Flags().Bool("dev", false, "从开发依赖项中移除 (暂未实现)")
	rootCmd.AddCommand(removeCmd)
	rootCmd.AddCommand(lockCmd)
	rootCmd.AddCommand(syncCmd)
	rootCmd.AddCommand(freezeCmd)
}

// --- 主函数 ---
func main() {
	log.SetFlags(0)
	if err := rootCmd.Execute(); err != nil {
		os.Exit(1)
	}
}

// ```

// **如何运行:**

// 1.  **保存代码** 为 `main.go`。
// 2.  **更新依赖:** 运行 `go mod tidy` (它会自动处理 `golang.org/x/mod/semver`)。
// 3.  **构建:** `go build -o vv` (或 `vv.exe`)。
// 4.  **查看可用版本:**
//     ```bash
//     ./vv python list --available
//     ```
//     这会调用 GitHub API，然后列出适用于你当前操作系统的 Python 版本。
// 5.  **查看已安装版本:**
//     ```bash
//     ./vv python list
//     ```
//     这会列出 `~/.vv/pythons` 目录下已安装且有效的版本，并进行排序。

// **后续步骤:**

// * **实现项目级别的 `vv python use`:** 创建 `.python-version` 文件。
// * **清理 Shim:** 在 `vv python uninstall` 时移除无效的 shim。
// * **依赖管理:**
//     * 实现 `vv install -r requirements.txt` (通过调用 `pip`)。
//     * 实现 `vv freeze` (通过调用 `pip freeze`)。
//     * 逐步实现基于 `pyproject.toml` 的依赖管理（这是最大的挑战）。

// 现在 `vv` 可以更好地帮助用户发现和管理 Python 版
